package com.zdft.promotion.common.service.impl;

import com.zdft.promotion.common.dao.EnCodeDao;
import com.zdft.promotion.common.dao.ds.DS;
import com.zdft.promotion.common.dao.ds.DSRoute;
import com.zdft.promotion.common.dao.ds.DataSourceContextHolder;
import com.zdft.promotion.common.service.BusinessException;
import com.zdft.promotion.common.service.api.IEnCodeService;
import oracle.jdbc.OracleTypes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

@Service
@DS(DSRoute.ERP)
@SuppressWarnings("all")
public class EnCodeServiceImpl implements IEnCodeService {

    @Autowired
    EnCodeDao enCodeDao;

    @Autowired
    JdbcTemplate jdbcTemplate;

    /**
     * 拼音码
     */
    public final static String PY = "py";

    /**
     * 五笔码
     */
    public final static String WB = "wb";


    @Override
    public String getEanCode(String tableName, long length) {
        Long id = null;
        try {
            id = getPk(tableName).longValue();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        String eanCode = getVerifyBit(id, length);
        return eanCode;
    }

    @Override
    public Integer getPk(String tableName) {
        Integer iRet = (Integer) jdbcTemplate.execute(
                new CallableStatementCreator() {
                    public CallableStatement createCallableStatement(
                            Connection con) throws SQLException {
                        String storedProc = "{call get_seq(?,?)}";// 调用的sql
                        CallableStatement cs = con.prepareCall(storedProc);
                        cs.setString(1, tableName);// 设置输入参数的值
                        cs.registerOutParameter(2, OracleTypes.INTEGER);// 注册输出参数的类型
                        return cs;
                    }
                }, new CallableStatementCallback() {
                    public Object doInCallableStatement(CallableStatement cs)
                            throws SQLException, DataAccessException {
                        cs.execute();
                        return cs.getInt(2);// 获取输出参数的值
                    }
                });
        return iRet;
    }

    private String getVerifyBit(Long szCode, long length) {
        String strCode = String.valueOf(szCode);
        if (String.valueOf(szCode) == null || String.valueOf(szCode).length() > length) {
            throw new BusinessException("0707");
        }
        for (int i = 0; i < length - 1 - String.valueOf(szCode).length(); i++) {
            strCode = "0" + strCode;
        }
        int nNum1 = 0;
        int nNum2 = 0;
        int nNum3 = 0;
        for (int i = strCode.length() - 1; i >= 0; i--) {
            if (i % 2 == 0) {
                nNum1 += Integer.parseInt(String.valueOf(strCode.charAt(i)));// 奇数
            } else {
                nNum2 += Integer.parseInt(String.valueOf(strCode.charAt(i)));
                // 偶数
            }
        }
        nNum3 = nNum1 + nNum2 * 3;
        int t;
        if (nNum3 % 10 > 0)
            t = 10 - (nNum3 % 10);
        else
            t = 0;
        strCode += t;
        return strCode;
    }

    @Override
    public Map<String, String> getWpCode(String source) {
        String[] arr = new String[2];
        try {
            DataSourceContextHolder.setDB(DSRoute.ERP);
            getWpCode(source, arr);
        } finally {
            DataSourceContextHolder.clearDB();
        }
        Map<String, String> map = new HashMap<>();
        map.put(WB, arr[1]);
        map.put(PY, arr[0]);
        return map;
    }

    /**
     * 生成五笔码
     *
     * @param chn 编码内容
     * @param sPy 拼音码
     * @param sWb 五笔码
     * @return 成功
     */
    public Integer getWpCode(String chn, String[] arr) {
        Integer iRet = null;
        try {
            iRet = (Integer) jdbcTemplate.execute(
                    new CallableStatementCreator() {
                        public CallableStatement createCallableStatement(
                                Connection con) throws SQLException {
                            String storedProc = "{call get_chncode(?,?,?,?)}";// 调用的sql
                            CallableStatement cs = con.prepareCall(storedProc);
                            cs.setString(1, chn);// 设置输入参数的值
                            cs.registerOutParameter(2, 12);
                            cs.registerOutParameter(3, 12);
                            cs.registerOutParameter(4, 4);
                            return cs;
                        }
                    }, new CallableStatementCallback() {
                        public Object doInCallableStatement(CallableStatement cs)
                                throws SQLException, DataAccessException {
                            cs.execute();
                            arr[0] = cs.getString(2);
                            arr[1] = cs.getString(3);
                            return cs.getInt(4);// 获取输出参数的值
                        }
                    });
        } catch (Exception ex) {
        } finally {
        }
        return iRet;
    }
}
